import {
  emitterAndTaker,
  equals,
  getLng,
  isHas,
  isNotEmpty,
  QueueElementBase,
  REVERSE_CONTAINER_ACTION,
  strFormat,
  toFixedHandler,
  UPLOADING_FILE_SUBSCRIBE_DEFINE,
  UploadProgressState,
} from "@/utils/uploader";
import { ref } from "vue";

export type QueueElementBaseExtend = Required<
  QueueElementBase & {
    // 进度状态
    stateDesc: string;
    // 下载文件大小
    downSize: number;
    // 剩余时间
    remainingTime: number;
  }
>;
const allProgress = ref<Array<QueueElementBaseExtend>>([]);
export type ProgressStateType = typeof allProgress;
// 表示 全局排序顺序
let globalSortFlag = true;

/**
 * 取消 进度的事件
 *
 * @author lihh
 * @param uniqueCode 唯一的值
 */
function cancelProgressHandler(uniqueCode: string) {
  // 先 提交状态, 交给jdk 自行清空状态
  emitterAndTaker.emit(
    REVERSE_CONTAINER_ACTION,
    uniqueCode,
    UploadProgressState.Canceled,
  );

  // 判断是否已经完成状态
  const idx = allProgress.value.findIndex((item) =>
    equals(item.uniqueCode, uniqueCode),
  );
  if (equals(idx, -1)) return;

  // 修改状态 && 移动要删除的元素
  const allDeletedElement = allProgress.value.splice(idx, 1);
  for (const el of allDeletedElement) el.type = UploadProgressState.Canceled;
  allProgress.value[globalSortFlag ? "push" : "unshift"](...allDeletedElement);
}

/**
 * 暂停 进度的事件
 *
 * @author lihh
 * @param uniqueCode 唯一的值
 */
function pauseProgressHandler(uniqueCode: string) {
  emitterAndTaker.emit(
    REVERSE_CONTAINER_ACTION,
    uniqueCode,
    UploadProgressState.Pause,
  );
}

/**
 * 表示 大文件上传的 hook
 *
 * @author lihh
 * @param sortFlag 排序的状态 true 向后添加 向前添加
 * @return [ProgressStateType, (uniqueCode: string) => void, (uniqueCode: string) => void] [上述的状态, 取消事件, 暂停事件]
 */
export function useBigFileUpload(
  sortFlag = true,
): [
  ProgressStateType,
  (uniqueCode: string) => void,
  (uniqueCode: string) => void,
] {
  globalSortFlag = sortFlag;

  // 添加收到消息的订阅事件
  emitterAndTaker.on(
    UPLOADING_FILE_SUBSCRIBE_DEFINE,
    function (el: QueueElementBaseExtend) {
      // 判断是否存在 用来判断是否要添加
      let existingElement = allProgress.value.find((item) =>
        equals(item.uniqueCode, el.uniqueCode),
      );
      // 判断 元素是否存在
      if (existingElement) {
        existingElement.type = el.type;
        // 判断 downSize 是否存在
        if (!isHas(existingElement, "downSize")) existingElement.downSize = 0;

        // 修改显示描述
        existingElement.stateDesc = getLng(existingElement!.type);
        existingElement.networkSpeed = el.networkSpeed;
        // 以 秒 为单位
        existingElement.remainingTime = toFixedHandler(
          (el.fileSize - existingElement.downSize) / el.networkSpeed,
          0,
        );
      }

      switch (el.type) {
        case UploadProgressState.Prepare: {
          if (isNotEmpty(existingElement)) return;

          existingElement = el;
          existingElement.downSize = 0;
          existingElement.remainingTime = toFixedHandler(
            (el.fileSize - existingElement.downSize) / el.networkSpeed,
            0,
          );

          // 如果是准备阶段的话 就要添加了
          allProgress.value[sortFlag ? "push" : "unshift"](el);
          break;
        }
        case UploadProgressState.RefreshRetry: {
          if (isNotEmpty(existingElement)) return;

          existingElement = el;
          existingElement!.downSize =
            (existingElement!.progress * existingElement!.fileSize) / 100;

          allProgress.value[sortFlag ? "push" : "unshift"](el);
          break;
        }
        case UploadProgressState.Uploading: {
          // 从 这里进行进度条累加
          const progress = el.progress;

          existingElement!.progress = toFixedHandler(
            progress > 100 ? 100 : progress,
            2,
          );
          existingElement!.downSize = toFixedHandler(
            (progress * existingElement!.fileSize) / 100,
            2,
          );
          break;
        }
        // 判断是否断点续传
        case UploadProgressState.BreakPointUpload: {
          // 断点续传中 直接设置滚动状态
          existingElement!.progress = toFixedHandler(el.progress, 2);
          break;
        }
        // 判断是否重试中
        case UploadProgressState.Retry: {
          existingElement!.stateDesc = strFormat(
            existingElement!.stateDesc,
            el.retryTimes + "",
          );
          break;
        }
        // 表示 这是一个取消状态
        case UploadProgressState.Canceled: {
          // todo 可以自行添加逻辑
          break;
        }
        case UploadProgressState.Merge:
        case UploadProgressState.QuickUpload:
        case UploadProgressState.Done: {
          existingElement!.progress = 100;
          existingElement!.downSize = el.fileSize;
          break;
        }
        // 表示错误请求
        case UploadProgressState.RequestError: {
          // 修改错误提示
          existingElement!.stateDesc = strFormat(
            existingElement!.stateDesc,
            el.requestErrorMsg,
          );
          break;
        }
      }
    },
  );

  return [allProgress, cancelProgressHandler, pauseProgressHandler];
}
